<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<title>基础：10、组件 自定义事件  使用v-on绑定自定义事件</title>
	<script type="text/javascript" src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>	
	<div id="counter-event-example">
		<p>{{ total }}</p>
		<button-counter v-on:increment="incrementTotal"></button-counter>
		<button-counter v-on:increment="incrementTotal"></button-counter>
	</div><br/>

	<div id="native">
		<my-component v-on:click="testNative('button1')"></my-component>
		<my-component v-on:click.native="testNative('button2')"></my-component>
	</div>

	<script type="text/javascript">
		// 在前面事件处理器那一节介绍了使用v-on指令来监听事件
		// 其使用形式为 v-on:Event="Method" 
		// @param  Event  监听事件名，如click(点击事件)、focus(鼠标聚焦)等
		// @param  Method  事件发生触发方法或函数  
		
		// Event除了是默认的事件之外，还可以使用自定义的事件
		// 解析: 这里定义了一个 button-counter 的组件，并且监听了组件的点击事件，
		//       一旦这个组件的实例元素被点击，即触发increment方法，该方法在组件
		//       methods属性了被定义，一旦方法被执行，则使用$emit触发increment自
		//       定义事件，这时组件的外层即父组件接收到该信号
		//       
		//       ----------------------- 我是分隔线 ----------------------------
		//       
		//       当父组件被告知发生了自定义事件increment时，子组件其实已经完成了
		//       它的历史使命，事件传递到外层，告诉他爸：“嘿，我触发increment这个
		//       事件了”。（PS.注意这里的自定义组件名是由$emit里面的字符串决定的）
		//       
		//       接下来的事情，老爸接管，我们把目光转移到vm这个vue实例，button-counter
		//       触发了increment事件，使得老爹vue实例中定义的incrementTotal方法被调用，
		//       父组件的total变量加1
		//       
		//       ------------------- 自定义事件的强大之处？----------------------
		//       
		//       1、实现了子组件内部事件和父组件外部事件的解耦，子组件想做到的是，
		//       	当我发生点什么时，老爸为我完成点处理
		//       	对子组件来说：老爸怎么处理我不用管
		//       	对父组件来说：儿子什么时候发出这个信号劳资也不用管
		//       	
		//       2、子组件自定义事件触发条件完全由子组件内部来进行控制，这种事件触发
		//          的自由性和灵活性为业务逻辑的调整提供了强大的灵活性
		Vue.component('button-counter',{
			template: '<button v-on:click="increment">{{ counter }}</button>',
			data: function(){
				return { counter: 0 }
			},
			// 组件在methods属性里定义自定义事件
			methods: {
				increment: function(){
					this.counter += 1
					this.$emit('increment')   // 触发自定义事件
				}
			}
		})

		var vm = new Vue({
			el: '#counter-event-example',
			data: {
				total: 0
			},
			methods: {
				incrementTotal: function(){
					this.total += 1
				}
			}
		})	

		// 在上面的例子中组件外层监听的是increment方法，如果在外层想监听原生的方法如click，需要在后面再加一个.native
		Vue.component('my-component',{
			template: '<button>test .native</button>'
		})
		// 测试可知，在vm2中
		// 第一个组件没有加.native没有成功执行testNative方法因为事件默认被<my-component>标签阻止了
		// 第二个组件加了.native，改变了默认的标签状态属性，相当于js中的addEventListener自己给元素添加事件监听器
		var vm2 = new Vue({
			el: '#native',
			methods: {
				testNative: function(msg){
					alert(msg)
				}
			}
		})
	</script>
</body>
</html>
<!-- 代码均通过测试，有什么纰漏欢迎联系 QQ:1123176978  Wechat:hyhlovehuanong -->